﻿#include "SDL_Canvas.h"

#define SDL_PLATFORM				((SDL_CPlatform*)GAF_pTHEPLATFORM)

#define SDL_FREE_SURFACE(_psfFree) \
		{SDL_PLATFORM->DeleteSurface(_psfFree); (_psfFree) = NULL;}

#define SDL_TRANSFORM_BUFFER_CONST		100

enum ColourArray{B, G, R, A};
#define COLOUR_ARRAY(_nColour)			((BYTE*)&_nColour)

SDL_CCanvas::SDL_CCanvas() :
	m_pMainSurface(NULL)
{
	m_rMainArea.Set(0, 0, 0, 0);
}

SDL_CCanvas::~SDL_CCanvas()
{
	SDL_Surface* _pSurface = NULL;

	MapSurfaceBuffer::iterator _it = m_mapTransformBuffer.begin();
	while(_it != m_mapTransformBuffer.end())
	{
		_pSurface = _it->second;
		m_mapTransformBuffer.erase(_it);
		SDL_FREE_SURFACE(_pSurface);

		_it = m_mapTransformBuffer.begin();
	}
}

bool SDL_CCanvas::OnInit(GAF_DWindowHandle hWindow)
{
	GAF_CHECK_R(hWindow != NULL, false);
	m_pMainSurface = (SDL_Surface*)hWindow;
	m_rMainArea.Set(0, 0, m_pMainSurface->w, m_pMainSurface->h);
	return true;
}

bool SDL_CCanvas::OnRender()
{
	return RenderGraphics(m_pRoot);
}

void SDL_CCanvas::SetGraphicsTree(GAF_CGraphics* pRoot)
{
	m_pRoot = pRoot;
}

void SDL_CCanvas::ClearGarphics()
{
	m_pRoot = NULL;
}

bool SDL_CCanvas::RenderGraphics(GAF_CGraphics* pGraphics)
{
	if(!LockSurface(m_pMainSurface))
		return false;

	if(pGraphics->GetScreenVisible())
	{
		if(pGraphics->OnPreRender(pGraphics))
		{
			switch(pGraphics->GetGType())
			{
			case GAF_GRAPHICS_FACE:
			case GAF::GRAPHICS_COMMANDFACE:
				{
					FOREACH_P(GAF_CGraphics, pChild, pGraphics)
					{
						RenderGraphics(pChild);
					}
				}
				break;
			case GAF_GRAPHICS_IMAGE:
				{
					GAF_CImage* _pImage = (GAF_CImage*)pGraphics;

					if(_pImage->GetImageHandle(true) == NULL)
						break;

					SImageInfo _iiRender;
					SetRenderInfo(pGraphics, &_iiRender);
				
					_iiRender.hImage	= _pImage->GetImageHandle(true);
					_iiRender.pbPixelBit	= _pImage->GetImageInfo_a().nBitsPixel;
					_iiRender.rClip		= _pImage->GetClip_a();

					RenderImage(_iiRender);
				}
				break;
			case GAF_GRAPHICS_TEXT:
				{
					GAF_CText* _pText = (GAF_CText*)pGraphics;
					if(_pText->GetText_a() == "")
						break;

					STextInfo _tiRender;
					SetRenderInfo(pGraphics, &_tiRender);

					_tiRender.strText	= _pText->GetText_a();
					_tiRender.strFontFile	= _pText->GetFontFile_a();
					_tiRender.nFontSize	= _pText->GetSceneFontSize();
					_tiRender.fsFontStyle	= _pText->GetFontStyle_a();
					_tiRender.nSpace	= _pText->GetSpace_a();
					_tiRender.cFront	= _pText->GetFrontColour_a();
					_tiRender.cBack		= _pText->GetBackColour_a();
					_tiRender.hTexture	= _pText->GetTexture_a();
					_tiRender.nStrokeSize	= _pText->GetStrokeSize_a();
					_tiRender.cStroke	= _pText->GetStrokeColour_a();

					RenderText(_tiRender);
				}
				break;
			case GAF_GRAPHICS_EFFECT:
				{
					SImageInfo _iiRender;
					SetRenderInfo(pGraphics, &_iiRender);

					_iiRender.hImage		= ((GAF_CEffect*)pGraphics)->GetFrameImageHandle();
					_iiRender.pbPixelBit		= 32;
					_iiRender.rClip			= ((GAF_CEffect*)pGraphics)->GetClip_a();

					RenderImage(_iiRender);
				}
				break;
			case GAF_GRAPHICS_OTHER:
				pGraphics->OnRender();
				break;
			}
		}
	}

	UnlockSurface(m_pMainSurface);

	return true;
}

void SDL_CCanvas::SetRenderInfo(GAF_CGraphics* pGraphics, SGraphicsInfo* pgiRender)
{
	pgiRender->nPosX		= pGraphics->GetScreenPosX();		
	pgiRender->nPosY		= pGraphics->GetScreenPosY();		
	pgiRender->aAnchor		= pGraphics->GetAnchor_a();	
	pgiRender->atAnchorOffset	= pGraphics->GetOffset_a();
	pgiRender->bAlpha		= pGraphics->GetScreenAlpha();		
	pgiRender->dAngle		= pGraphics->GetScreenAngle();		
	pgiRender->dZoomX		= pGraphics->GetScreenZoomX();		
	pgiRender->dZoomY		= pGraphics->GetScreenZoomY();		
	pgiRender->through		= pGraphics->GetScreenThrough();	
	pgiRender->rCanvasArea		= GAF_RECT_NULL;
	pgiRender->pbdlInformation	= pGraphics->AddInfos();
}

bool SDL_CCanvas::RenderImage(SImageInfo& iiRender)
{
	static bool s_isReturn;
	s_isReturn = true;

	if(iiRender.hImage == NULL)
		return true;

	// 转换Surface资源
	static SDL_Surface* s_pSurface;
	static SDL_Surface* s_pTransform;
	s_pSurface = (SDL_Surface*)iiRender.hImage;
	s_pTransform = NULL;

	// 缩放 与 旋转
	s_pTransform = NULL;
	static STD_STRING s_strImageForm;
	if(iiRender.dAngle != GAF_ANGLE_DEFAULT
		|| iiRender.dZoomX != GAF_ZOOM_DEFAULT
		|| iiRender.dZoomY != GAF_ZOOM_DEFAULT)
	{
		static char s_szBufferName[100];
		s_strImageForm = iiRender.pbdlInformation->GetString(GAF_INFO_IMAGEFROM);

		if(s_strImageForm.size() > 0)
		{
// 			SYS_MEMSET(s_szBufferName, 0, sizeof(s_szBufferName));
			SYS_SPRINTF(s_szBufferName, "%s_%f_%f_%f",
				s_strImageForm.c_str(), iiRender.dAngle, iiRender.dZoomX, iiRender.dZoomY);

			if(m_mapTransformBuffer.find(s_szBufferName) != m_mapTransformBuffer.end())
				s_pTransform = m_mapTransformBuffer[s_szBufferName];
		}

 		if(s_pTransform == NULL)
		{
			// 缩放
			s_pTransform = AngleZoom(s_pSurface, iiRender.dAngle, iiRender.dZoomX, iiRender.dZoomY);

			// 存储缓存
			if(s_strImageForm.size() > 0 && s_pTransform != NULL)
			{
// 				// 变化出来的图像均为32位，对于jpg的图像无法用于像素混合，故在此更改为元像素位数
// 				s_pTransform->format->BitsPerPixel = s_pSurface->format->BitsPerPixel;


				// 查找调节器中的记录，并删除
				static LstBufferAdjust::const_iterator s_citList;
				s_citList = m_lstTransformAdjust.begin();
				for(; s_citList != m_lstTransformAdjust.end(); s_citList++)
				{
					if(*s_citList == s_szBufferName)
					{
						m_lstTransformAdjust.erase(s_citList);
						break;
					}
				}

				// 如果缓存数量大于指定数量，删除调节器中最上面的（即为最不常用的）
				if(m_mapTransformBuffer.size() >= SDL_TRANSFORM_BUFFER_CONST)
				{
					s_citList = m_lstTransformAdjust.begin();
					STD_STRING _str =  *s_citList;
					static MapSurfaceBuffer::iterator s_itMap;
					s_itMap = m_mapTransformBuffer.find(*m_lstTransformAdjust.begin());

					SDL_FREE_SURFACE(s_itMap->second);
					m_mapTransformBuffer.erase(s_itMap);
					m_lstTransformAdjust.pop_front();
				}

				// 添加缓存与调节器记录
				m_mapTransformBuffer[s_szBufferName] = s_pTransform;
				m_lstTransformAdjust.push_back(s_szBufferName);
			}
		}

		if(s_pTransform != NULL)
		{
			// 设置绘制对象
			s_pSurface = s_pTransform;
			if(s_strImageForm.size() > 0)
				s_pTransform = NULL;
		}
	}

	// 计算尺寸
	static GAF_SRect s_rImageClip;

	if(iiRender.rClip == GAF_RECT_NULL)
	{
		iiRender.rClip.nWidth = s_pSurface->w;
		iiRender.rClip.nHeight = s_pSurface->h;
	}
	s_rImageClip.nWidth = iiRender.rClip.nWidth;
	s_rImageClip.nHeight = iiRender.rClip.nHeight;

	// 计算坐标
	s_rImageClip.nX = iiRender.nPosX + iiRender.atAnchorOffset.nX;
	if((iiRender.aAnchor & GAF_ANCHOR_HMASK) == GAF_ANCHOR_LEFT) {}
	else if((iiRender.aAnchor & GAF_ANCHOR_HMASK) == GAF_ANCHOR_HCENTER)
		s_rImageClip.nX -= s_rImageClip.nWidth >> 1;
	else if((iiRender.aAnchor & GAF_ANCHOR_HMASK) == GAF_ANCHOR_RIGHT)
		s_rImageClip.nX -= s_rImageClip.nWidth;

	s_rImageClip.nY = iiRender.nPosY + iiRender.atAnchorOffset.nY;
	if((iiRender.aAnchor & GAF_ANCHOR_VMASK) == GAF_ANCHOR_TOP) {}
	else if((iiRender.aAnchor & GAF_ANCHOR_VMASK) == GAF_ANCHOR_VCENTER)
		s_rImageClip.nY -= s_rImageClip.nHeight >> 1;
	else if((iiRender.aAnchor & GAF_ANCHOR_VMASK) == GAF_ANCHOR_BUTTON)
		s_rImageClip.nY -= s_rImageClip.nHeight;

	// 计算位置
	if(iiRender.through != GAF_THROUGH_NONE)
	{
		s_rImageClip.nX = s_rImageClip.nX % m_pMainSurface->w;
		if(s_rImageClip.nX < 0) s_rImageClip.nX += m_pMainSurface->w;
		s_rImageClip.nY = s_rImageClip.nY % m_pMainSurface->h;
		if(s_rImageClip.nY < 0) s_rImageClip.nY += m_pMainSurface->h;
	}
	else
	{
		if(s_rImageClip.Right() <= 0 || s_rImageClip.Left() >= m_pMainSurface->w ||
			s_rImageClip.Button() <= 0 || s_rImageClip.Top() >= m_pMainSurface->h)
		{
			s_isReturn = true;
			goto SDL_GOTO_RENDERIMAGE_RETURN;
		}
	}

	// 特殊混合与绘制
	s_isReturn &= RenderSurface(s_pSurface,
		s_rImageClip.nX, s_rImageClip.nY,
		iiRender.rClip, iiRender.pbPixelBit, iiRender.bAlpha);

	if(iiRender.through != GAF_THROUGH_NONE)
	{ // 暂时不考虑绘制大于屏幕尺寸的图像穿越屏幕时的遮挡问题
		// 垂直穿越
		if(iiRender.through == GAF_THROUGH_HORIZONTAL || iiRender.through == GAF_THROUGH_BOTH)
		{
			if(s_rImageClip.Right() > m_pMainSurface->w)
			{
				s_isReturn &= RenderSurface(s_pSurface,
					s_rImageClip.nX - m_pMainSurface->w, s_rImageClip.nY,
					iiRender.rClip, iiRender.pbPixelBit, iiRender.bAlpha);
			}
		}

		// 水平穿越
		if(iiRender.through == GAF_THROUGH_VERTICAL || iiRender.through == GAF_THROUGH_BOTH)
		{
			if(s_rImageClip.Button() > m_pMainSurface->h)
			{
				s_isReturn &= RenderSurface(s_pSurface,
					s_rImageClip.nX, s_rImageClip.nY - m_pMainSurface->h,
					iiRender.rClip, iiRender.pbPixelBit, iiRender.bAlpha);
			}
		}

		// 都穿越
		if(iiRender.through == GAF_THROUGH_BOTH)
		{
			if(s_rImageClip.Right() > m_pMainSurface->w && s_rImageClip.Button() > m_pMainSurface->h)
			{
				s_isReturn &= RenderSurface(s_pSurface,
					s_rImageClip.nX - m_pMainSurface->w, s_rImageClip.nY - m_pMainSurface->h,
					iiRender.rClip, iiRender.pbPixelBit, iiRender.bAlpha);
			}
		}
	}

SDL_GOTO_RENDERIMAGE_RETURN:
	if(s_pTransform != NULL)
		SDL_FREE_SURFACE(s_pTransform)

	return s_isReturn;
}

bool SDL_CCanvas::RenderText(STextInfo& tiRender)
{
	static bool s_isReturn;
	s_isReturn = true;
	SDL_Surface* _pText = NULL;

	// 转换文字为UTF-16格式
	int _nConvLen = ConvertText(tiRender.strText.c_str());
	char* _pszConvText = new char[_nConvLen];
	SYS_MEMSET(_pszConvText, 0, sizeof(char) * _nConvLen);
	if(ConvertText(tiRender.strText.c_str(), _pszConvText) < 0)
	{
		GAF_ERRMARK();
		s_isReturn = false;
		goto SDL_GOTO_RENDERTEXT_RETURN;
	}

	// 加载字体
	TTF_Font* _pTTF = GetFont(tiRender.strFontFile, tiRender.nFontSize);
	if(_pTTF == NULL)
	{
		GAF_ERRMARK();
		s_isReturn = false;
		goto SDL_GOTO_RENDERTEXT_RETURN;
	}

	// 设置字体样式
	TTF_SetFontStyle(_pTTF, (int)tiRender.fsFontStyle);
// 	TTF_SetFontHinting(_pTTF, 3);
// 	TTF_SetFontKerning(_pTTF, 50);
	TTF_SetFontOutline(_pTTF, 0);

	// 设置纹理字体前后背景颜色
	if(tiRender.hTexture != NULL)
	{
		tiRender.cFront = GAF_COLOUR_WHITE;
		tiRender.cBack = GAF_COLOUR_BLACK;
	}

	// 创建文字
	_pText = CreateTextSurface(_pTTF, _pszConvText, tiRender.cFront, tiRender.cBack);
	if(_pText == NULL)
	{
		GAF_ERRMARK();
		s_isReturn = false;
		goto SDL_GOTO_RENDERTEXT_RETURN;
	}

	// 纹理绘制
	if(tiRender.hTexture != NULL)
	{
		SDL_Surface* _pTexture = (SDL_Surface*)tiRender.hTexture;
		SDL_Surface* _pTextureZoom = AngleZoom(_pTexture, 0,
			(double)_pText->w / (double)_pTexture->w, (double)_pText->h / (double)_pTexture->h);

		if(_pTextureZoom == NULL)
		{
			s_isReturn = false;
			goto SDL_GOTO_RENDERTEXT_RETURN;
		}

		SDL_Surface* _pTextureText = MarkSurface(_pTextureZoom, _pText);
		SDL_FREE_SURFACE(_pTextureZoom);

		if(_pTextureText == NULL)
		{
			s_isReturn = false;
			goto SDL_GOTO_RENDERTEXT_RETURN;

		}

		SDL_FREE_SURFACE(_pText);
		_pText = _pTextureText;
	}

	// 描边绘制
	if(tiRender.nStrokeSize > 0 && tiRender.cStroke.bAlpha > 0)
	{
		TTF_SetFontOutline(_pTTF, tiRender.nStrokeSize);

		SDL_Surface* _pStroke = CreateTextSurface(_pTTF, _pszConvText, tiRender.cStroke, GAF_COLOUR_TRANSPARENT);

		if(LockSurface(_pStroke))
		{
			BlendSurface(_pStroke, _pText,
				(_pStroke->w - _pText->w) >> 1, ((_pStroke->h - _pText->h + 3) >> 1),
				GAF_RECT_NULL, GAF_RECT_NULL, 255);
		}
		UnlockSurface(_pStroke);

		SDL_FREE_SURFACE(_pText);
		_pText = _pStroke;
	}

	// 绘制
	SImageInfo _iiRender;
	memcpy((SGraphicsInfo*)&_iiRender, (SGraphicsInfo*)&tiRender, sizeof(SGraphicsInfo));
	_iiRender.hImage	= _pText;
	_iiRender.pbPixelBit	= 32;
	_iiRender.rClip		= GAF_RECT_NULL;

	s_isReturn &= RenderImage(_iiRender);

SDL_GOTO_RENDERTEXT_RETURN:
	
	delete [] _pszConvText;
	SDL_FREE_SURFACE(_pText);

	return s_isReturn;
}

bool SDL_CCanvas::RenderSurface(SDL_Surface* pSrcSurface,
	int nX, int nY, GAF_SRect rSrcClip, SDL_DPixelBit pb, BYTE bAlpha)
{
	if(rSrcClip == GAF_RECT_NULL)
	{
		rSrcClip.nX = 0;
		rSrcClip.nY = 0;
		rSrcClip.nWidth = pSrcSurface->w;
		rSrcClip.nHeight = pSrcSurface->h;
	}

	if(pb == 0)
		pb = pSrcSurface->format->BitsPerPixel;

	if(bAlpha < GAF_ALPHA_DEFAULT
// 		|| !(rSrcClip.nX == 0 && rSrcClip.nY == 0 &&
// 		rSrcClip.nWidth == pSrcSurface->w && rSrcClip.nHeight == pSrcSurface->h)
		)
	{
		if(pb == SDL_PIXELBIT_32)
			return BlendSurface(m_pMainSurface, pSrcSurface, nX, nY, m_rMainArea, rSrcClip, bAlpha);
		else
			return AlphaSurface(m_pMainSurface, pSrcSurface, nX, nY, m_rMainArea, rSrcClip, bAlpha);
	}
	else
	{
		return DrawSurface(m_pMainSurface, pSrcSurface, nX, nY, m_rMainArea, rSrcClip);
	}
}

bool SDL_CCanvas::DrawSurface(SDL_Surface* pDisSurface, SDL_Surface* pSrcSurface,
				    int nX, int nY, GAF_SRect rDisArea, GAF_SRect rSrcClip)
{
	if(rDisArea == GAF_RECT_NULL)
	{
		rDisArea.nX = 0;
		rDisArea.nY = 0;
		rDisArea.nWidth = pDisSurface->w;
		rDisArea.nHeight = pDisSurface->h;
	}

	if(rSrcClip == GAF_RECT_NULL)
	{
		rSrcClip.nX = 0;
		rSrcClip.nY = 0;
		rSrcClip.nWidth = pSrcSurface->w;
		rSrcClip.nHeight = pSrcSurface->h;
	}

	SDL_Rect _rDis;
	_rDis.x = nX;
	_rDis.y = nY;
	SDL_Rect _rScr;
	_rScr.x = rSrcClip.nX;
	_rScr.y = rSrcClip.nY;
	_rScr.w = rSrcClip.nWidth;
	_rScr.h = rSrcClip.nHeight;

	SDL_BlitSurface(pSrcSurface, &_rScr, pDisSurface, &_rDis);

	return true;
}

bool SDL_CCanvas::AlphaSurface(SDL_Surface* pDisSurface, SDL_Surface* pSrcSurface,
	int nX, int nY, GAF_SRect rDisArea, GAF_SRect rSrcClip, BYTE bAlpha)
{
	SDL_gfxSetAlpha(pSrcSurface, bAlpha);

	return DrawSurface(pDisSurface, pSrcSurface, nX, nY, rDisArea, rSrcClip);
}

bool SDL_CCanvas::BlendSurface(SDL_Surface* pDisSurface, SDL_Surface* pSrcSurface,
	int nX, int nY, GAF_SRect rDisArea, GAF_SRect rSrcClip, BYTE bAlpha)
{
	static GAF_SRect s_rDis, s_rSrc;
	static GAF_SPoint s_atDis, s_atSrc;
	static Uint32 s_nDis, s_nSrc;

	if(rDisArea == GAF_RECT_NULL)
	{
		rDisArea.nX = 0;
		rDisArea.nY = 0;
		rDisArea.nWidth = pDisSurface->w;
		rDisArea.nHeight = pDisSurface->h;
	}

	if(rSrcClip == GAF_RECT_NULL)
	{
		rSrcClip.nX = 0;
		rSrcClip.nY = 0;
		rSrcClip.nWidth = pSrcSurface->w;
		rSrcClip.nHeight = pSrcSurface->h;
	}

	// 调整原图绘制区域
	if(rSrcClip.Top() < 0)
	{
		nY += 0 - rSrcClip.nY;
		rSrcClip.Top(0);
	}
	if(rSrcClip.Button() > pSrcSurface->h)
	{
		rSrcClip.Button(pSrcSurface->h);
	}
	if(rSrcClip.Left() < 0)
	{
		nX += 0 - rSrcClip.nX;
		rSrcClip.Left(0);
	}
	if(rSrcClip.Right() > pSrcSurface->w)
	{
		rSrcClip.Right(pSrcSurface->w);
	}

	// 设置原图所在目标图的绘图区域
	s_rSrc.Set(nX, nY, rSrcClip.nWidth, rSrcClip.nHeight);

	// 计算相交区域
	if(rDisArea.Contains(s_rSrc))
	{
		s_rDis = s_rSrc;
	}
	else
	{
		s_rDis = rDisArea.Cut(s_rSrc);
	}

	if(s_rDis.nX < 0 || s_rDis.nY < 0 || s_rDis.nWidth == 0 || s_rDis.nHeight == 0)
		return false;

	// 设置原图绘制区域
	s_rSrc.Set(rSrcClip.nX + (s_rDis.nX - nX),
		rSrcClip.nY + (s_rDis.nY - nY),
		s_rDis.nWidth,
		s_rDis.nHeight);

	if(s_rSrc.nX < 0 || s_rSrc.nY < 0 || s_rSrc.nWidth == 0 || s_rSrc.nHeight == 0)
		return false;

	// 混合
	if(LockSurface(pSrcSurface))
	{
		s_atDis.Set(s_rDis.nX, s_rDis.nY);
		s_atSrc.Set(s_rSrc.nX, s_rSrc.nY);
		for(; s_atSrc.nY < (int)s_rSrc.Button(); s_atSrc.nY++)
		{
			for(; s_atSrc.nX < (int)s_rSrc.Right(); s_atSrc.nX++)
			{
				s_nDis = GetPixel(pDisSurface, s_atDis.nX, s_atDis.nY);
				s_nSrc = GetPixel(pSrcSurface, s_atSrc.nX, s_atSrc.nY);
				s_nDis = AlphaPixel(s_nDis, s_nSrc, (SDL_DPixelBit)(pSrcSurface->format->BytesPerPixel << 3), bAlpha);
				SetPixel(pDisSurface, s_atDis.nX, s_atDis.nY, s_nDis);

				s_atDis.nX++;
			}
			s_atSrc.nX = s_rSrc.nX;

			s_atDis.nX = s_rDis.nX;
			s_atDis.nY++;
		}
	}
	UnlockSurface(pSrcSurface);

	return true;
}

Uint32 SDL_CCanvas::AlphaPixel(Uint32 nDisColour, Uint32 nSrcColour, SDL_DPixelBit pbSrc, BYTE bAlpha)
{
	static Uint32 s_nRtnColour;
	static BYTE *s_pbDisColour, *s_pbSrcColour, *s_pbRtnColour;

	s_pbSrcColour = (BYTE*)&nSrcColour;

	if(bAlpha == 255 && s_pbSrcColour[A] == 255)
	{
		return nSrcColour;
	}

	s_nRtnColour = 0;
	s_pbDisColour = (BYTE*)&nDisColour;
	s_pbRtnColour = (BYTE*)&s_nRtnColour;

	if(pbSrc == SDL_PIXELBIT_32 && s_pbSrcColour[A] != 255)
		bAlpha = (bAlpha * s_pbSrcColour[A]) >> 8; // 255;

	s_pbRtnColour[R] = (s_pbSrcColour[R] * bAlpha + s_pbDisColour[R] * (255 - bAlpha)) >> 8; // 255;
	s_pbRtnColour[G] = (s_pbSrcColour[G] * bAlpha + s_pbDisColour[G] * (255 - bAlpha)) >> 8; // 255;
	s_pbRtnColour[B] = (s_pbSrcColour[B] * bAlpha + s_pbDisColour[B] * (255 - bAlpha)) >> 8; // 255;
	s_pbRtnColour[A] = (s_pbSrcColour[A] * bAlpha + s_pbDisColour[A] * (255 - bAlpha)) >> 8; // 255;

	return s_nRtnColour;
}

inline Uint32 SDL_CCanvas::GetPixel(SDL_Surface* pDisSurface, int nX, int nY)
{
	static UNUM32 s_nColour;

	SYS_MEMCPY(&s_nColour,
		((BYTE*)pDisSurface->pixels) + (pDisSurface->w * nY + nX) * pDisSurface->format->BytesPerPixel,
		pDisSurface->format->BytesPerPixel);

	return s_nColour;
}

inline void SDL_CCanvas::SetPixel(SDL_Surface* pDisSurface, int nX, int nY, Uint32 nColour)
{
	SYS_MEMCPY(((BYTE*)pDisSurface->pixels) + (pDisSurface->w * nY + nX) * pDisSurface->format->BytesPerPixel,
		&nColour, pDisSurface->format->BytesPerPixel);
}

SDL_Surface* SDL_CCanvas::AngleZoom(SDL_Surface* pSrcSurface, double dAngle, double dZoomX, double dZoomY)
{
	SDL_Surface* _pNew = rotozoomSurfaceXY(pSrcSurface, dAngle, dZoomX, dZoomY, 0);

	if(_pNew != NULL)
	{
		// 变化出来的图像均为32位，对于jpg的图像无法用于像素混合，故在此更改为元像素位数
		_pNew->format->BitsPerPixel = pSrcSurface->format->BitsPerPixel;
	}

	return _pNew;
}

SDL_Surface* SDL_CCanvas::MarkSurface(SDL_Surface* pSrcSurface, SDL_Surface* pMarkSurface)
{
	int _nWidth = GAF_MATH_MIN(pSrcSurface->w, pMarkSurface->w);
	int _nHeight = GAF_MATH_MIN(pSrcSurface->h, pMarkSurface->h);

	SDL_Surface* _pNew = SDL_PLATFORM->CreateSurface(_nWidth, _nHeight);
	_pNew = SDL_PLATFORM->FormatSurface(_pNew);

	if(_pNew == NULL)
		return NULL;

	Uint32 _nSrc = 0;
	Uint32 _nMark = 0;
	Uint32 _nNew = 0;

	BYTE* _pbSrc = NULL;
	BYTE* _pbMark = NULL;
	BYTE _bMarkAlpha = 0;

	for(int _nX = 0; _nX < _nWidth; _nX++)
	{
		for(int _nY = 0; _nY < _nHeight; _nY++)
		{
			_nSrc = GetPixel(pSrcSurface, _nX, _nY);
			_nMark = GetPixel(pMarkSurface, _nX, _nY);

			_pbSrc = (BYTE*)&_nSrc;
			_pbMark = (BYTE*)&_nMark;
// 			_bMarkAlpha = (_pbMark[R] + _pbMark[G] + _pbMark[B]) / 3;
			_bMarkAlpha = (COLOUR_ARRAY(_nMark)[R] + COLOUR_ARRAY(_nMark)[G] + COLOUR_ARRAY(_nMark)[B]) / 3;

			_nNew = GAF_ABGR_32(_pbSrc[R], _pbSrc[G], _pbSrc[B], _bMarkAlpha);
			SetPixel(_pNew, _nX, _nY, _nNew);
		}
	}

	return _pNew;
}

void SDL_CCanvas::FullFilling(SDL_Surface* pDisSurface, Uint32 nColour)
{
	if(pDisSurface->format->BitsPerPixel == 32)
	{
		for(int _nX = 0; _nX < pDisSurface->w; _nX++)
		{
			for(int _nY = 0; _nY < pDisSurface->h; _nY++)
			{
				SetPixel(pDisSurface, _nX, _nY, nColour);
			}
		}

// 		Uint32* _pnPixels = (Uint32*)(pDisSurface->pixels);
// 		int _nConst = pDisSurface->h * pDisSurface->w;
// 		for(int _i = 0; _i < _nConst; _i++)
// 		{
// 			_pnPixels[_i] = nColour;
// 		}
	}
}

int SDL_CCanvas::ConvertText(const char* pszScrText, char* pszConvText)
{
	size_t _stConvLen = 4;
	for (int _i = 0; pszScrText[_i]; _i++)
	{
		if((unsigned char)pszScrText[_i] > 127 )
		{
			_i++;
		}
		_stConvLen += 2;
	}

	if(pszConvText == NULL)
		return _stConvLen;

	iconv_t _icnCD = iconv_open("UTF-16//IGNORE", "gb18030");
	if(_icnCD == NULL)
	{
		GAF_ERRMARK();
		return -1;
	}

	size_t _stScrLen = SYS_STRLEN(pszScrText);

	if(iconv(_icnCD, &pszScrText, &_stScrLen, &pszConvText, &_stConvLen) == -1)
	{
		GAF_ERRMARK();
		return -1;       
	}

	iconv_close(_icnCD);

	return _stConvLen;
}

TTF_Font* SDL_CCanvas::GetFont(STD_STRING strFile, int nSize)
{
	char _szFontMark[100];
	SYS_SPRINTF(_szFontMark, "%s_%d", strFile.c_str(), nSize);

	TTF_Font* _pTTF = m_mapFonts[_szFontMark];

	if(_pTTF == NULL)
	{
		_pTTF = TTF_OpenFont(strFile.c_str(), nSize);
		if(_pTTF == NULL)
		{
			GAF_ERRMARK();
			return NULL;
		}
		m_mapFonts[_szFontMark] = _pTTF;
	}

	return _pTTF;
}

SDL_Surface* SDL_CCanvas::CreateTextSurface(TTF_Font* pTTF, char* pszText, GAF_SColour cFront, GAF_SColour cBack)
{
	SDL_Surface* _pTextImage = NULL;
	SDL_Colour _clFront = {cFront.bRed, cFront.bGreen, cFront.bBlue};

	_pTextImage = TTF_RenderUNICODE_Blended(pTTF, (Uint16*)pszText, _clFront);
	_pTextImage = SDL_PLATFORM->FormatSurface(_pTextImage);
	if(_pTextImage == NULL)
	{
		GAF_ERRMARK();
		return NULL;
	}

	SDL_Surface* _pBackImage = SDL_PLATFORM->CreateSurface(_pTextImage->w, _pTextImage->h);
	_pBackImage = SDL_PLATFORM->FormatSurface(_pBackImage);
	if(_pBackImage == NULL)
	{
		GAF_ERRMARK();
		SDL_FREE_SURFACE(_pTextImage);
		return NULL;
	}

	if(LockSurface(_pBackImage))
	{
		if(cBack != GAF_COLOUR_TRANSPARENT)
			FullFilling(_pBackImage, GAF_ABGR_32(cBack.bRed, cBack.bGreen, cBack.bBlue, cBack.bAlpha));
		BlendSurface(_pBackImage, _pTextImage, 0, 0, GAF_RECT_NULL, GAF_RECT_NULL, cFront.bAlpha);
	}
	UnlockSurface(_pBackImage);

	SDL_FREE_SURFACE(_pTextImage);

	return _pBackImage;
}

bool SDL_CCanvas::LockSurface( SDL_Surface* pSurface )
{
	if(SDL_MUSTLOCK(pSurface))
	{
		if(SDL_LockSurface(pSurface) < 0)
			return false;
	}

	return true;
}

void SDL_CCanvas::UnlockSurface( SDL_Surface* pSurface )
{
	if(SDL_MUSTLOCK(pSurface))
	{
		SDL_UnlockSurface(pSurface);
	}
}


